Canvas、SVG实现鼠标滑过某个区域高亮显示的方案说明

您所在的位置:网站首页 canvas svg性能 Canvas、SVG实现鼠标滑过某个区域高亮显示的方案说明

Canvas、SVG实现鼠标滑过某个区域高亮显示的方案说明

2023-07-10 21:50| 来源: 网络整理| 查看: 265

1、需求背景:

用户提供了某个厂区的底图(就一张静态图片),在底图中,划分了10个不规则区域,给了10个区域的高亮、开灯效果图片(切好了图),鼠标滑过每个区域的时候,要高亮显示,开灯的时候,显示开灯效果;看到这个需求的时候,挺懵的,有点不知从何下手,但是分析后,有2种可以实现的方案,具体方案如下:

2、方案说明

方案1:传统的div去定位,绝对定位,用css实现hover效果,click的时候设置active效果。

这种方案会存在问题。首先,划分的区域是不规则的,如果强行用div去定位,可能会导致区域重叠的问题;其次鼠标划过,鼠标高亮效果要完全和底图贴合,这一点其实不容易实现。而且浏览器全屏后,可能会导致位置出现偏差的问题,基于以上的考虑,我放弃了此方案。

方案2:用Canvas和SVG的方式实现。不规则的区域,手动取点,绘制路径,鼠标划过或鼠标点击的时候,判断鼠标坐标点是否在Path路径内,如果在某个区域内,就显示对应效果。但是要考虑一个问题,因为Path的点,我们是在某个分辨率基准下取点的,这就导致在不同屏幕分辨率下,会导致,无法取到点的问题,所以要重新计算鼠标坐标点。这种方案,全屏后,也不会说出现位置偏差,后面采用了此种方案,具体实现过程如下:

1、找一个容器,放背景图

2、 绘制canvas区域,并且在每个区域写上文字标识,绘制10个区域

drawImage(cb) { const that = this const img = new Image() img.src = backImg img.onload = function() { // 在Canvas中绘制图像 ctx.drawImage(img, 0, 0, canvas.width, canvas.height) for (let i = 0; i < that.svgShapeList.length; i++) { const shape = that.svgShapeList[i] ctx.fillStyle = '#ffff33' // 设置填充颜色 ctx.font = 'bold 14px Arial' ctx.textBaseline = 'middle' ctx.fillText(shape.name, shape.textX, shape.textY) // 绘制文本 } if (cb) { cb() } } } /** * @description 鼠标移出,移除效果,如果存在开灯效果继续显示开灯效果 */ renderCanvas() { this.drawImage(() => { for (let i = 0; i < this.svgShapeList.length; i++) { // 保存绘图状态 ctx.save() const shape = this.svgShapeList[i] if (shape.switchState) { this.fetchFile(shape) } // 恢复到之前保存的绘图状态 ctx.restore() } }) }, /** * @description 获取外部文件 */ fetchFile(shape) { // ctx.fillStyle = 'rgb(255, 255, 0,0.2)' // ctx.fill(shape.path) var image = new Image() image.src = baseImg image.onload = async () => { var pattern = await ctx.createPattern(image, 'repeat') ctx.fillStyle = pattern ctx.fill(shape.path) } },

3、接下来就是处理鼠标滑过、鼠标点击的问题了

判断坐标点位置的核心代码

const isInArea = ctx.isPointInPath(shape.path, mouseX, mouseY)

4、重新计算坐标点位:

setRatio() { const initialWidth = 1920 const initialHeight = 937 const targetWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth const targetHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight this.ratioX = initialWidth / targetWidth this.ratioY = initialHeight / targetHeight },

说明1920,937为绘制路径时,屏幕可视区域的基准值,这个根据自己的情况来定

然后再鼠标划过,鼠标点击的时候,要注意用当前坐标点乘以一个系数ratioX,ratioY

基本上就这样子了

反正就是要注意导入图片时,不要用路径,否则会出现闪烁的问题,因为一直从服务器请求资源,建议用base64。

完整代码就不粘了,有疑问或者有更好的方案,欢迎留言!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3